﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using OpenSoftStore.BusinessLogic.Member;
using OpenSoftStore.BusinessLogic.Money;
using OpenSoftStore.BusinessLogic.Product;
using OpenSoftStore.Orm;
using OpenSoftStore.Orm.Logic;
using OpenSoftStore.Orm.Model;
using OpenSoftStore.Orm.Print;
using OpenSoftStore.Orm.View;

namespace OpenSoftStore.BusinessLogic.Bill
{
    public class BillLogic : ABusinessLogic
    {
        #region Fields
        public MoneyLogic MoneyBll;
        public ProductLogic LgcProduct;
        public DinnerSaleLogic LgcDinnerSale;
        #endregion

        #region Constroct

        public BillLogic()
        {
            MoneyBll = new MoneyLogic();
            LgcProduct = new ProductLogic();
            LgcDinnerSale = new DinnerSaleLogic();
        }

        #endregion
        #region Methods

        #region Bill

        public List<P_Bill> GetBillPrint(string where = "", string orderBy = "")
        {
            string sql = " select T_Admin.Name as AdminName,T_Bill.*,T_Member.Name as MemberName,T_Member.CardId,T_Shop.Name as ShopName,T_Shop.Address as ShopAddress,T_Shop.Tel as ShopTel,T_Tree.Name as TreeName,(T_BillItem.Price * T_BillItem.Amount *T_BillItem.Discount) as ItemTotal, " +
                         " T_BillItem.Amount,T_BillItem.ItemName,T_BillItem.Price,T_BillItem.Discount as ItemDiscount " +
                         " from ((((T_Bill inner join T_Member on T_Bill.MemberId=T_Member.Id) " +
                         " inner join T_Shop on T_Bill.ShopId=T_Shop.Id) " +
                         " inner join T_Tree on T_Bill.TreeId=T_Tree.Id)" +
                         " inner join T_BillItem on T_Bill.Id=T_BillItem.BillId)" +
                         " inner join T_Admin on T_Bill.AdminId=T_Admin.Id ";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            //sql = sql + " order by T_Bill.AddTime desc ";
            if (!string.IsNullOrEmpty(orderBy)) sql = sql + orderBy;
            var bills = Spa.SelectWhere<P_Bill>(sql).ToList();
            foreach (var bill in bills)
            {
                bill.ItemCount = bills.Count;
                bill.AmountTotal = bills.Sum(m=>m.Amount);
            }
            if (!bills.Any()) return null;
            return bills;
        }

        public DataTable GetBillReport(string where = "", string orderBy = "")
        {
            string sql = " select T_Bill.*,T_Member.Name as MemberName,T_Member.CardId,T_Shop.Name as ShopName from (T_Bill inner join T_Member on T_Bill.MemberId=T_Member.Id) inner join T_Shop on T_Bill.ShopId=T_Shop.Id ";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            sql = sql + " order by T_Bill.AddTime desc";
            if (string.IsNullOrEmpty(orderBy)) sql = sql + orderBy;
            var data = Spa.RunSqLcmdDataSet(sql);
            if (data.Tables.Count == 0) return null;
            return data.Tables[0];
        }

        public DataTable GetProductReport(string where = "", string orderBy = "")
        {
            string sql = "  select T_BillItem.* from (T_BillItem inner join T_Product on T_BillItem.ProductId=T_Product.Id) inner join T_Bill on T_BillItem.BillId=T_Bill.Id  ";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            sql = sql + " order by T_Bill.AddTime desc";
            if (string.IsNullOrEmpty(orderBy)) sql = sql + orderBy;
            var data = Spa.RunSqLcmdDataSet(sql);
            if (data.Tables.Count == 0) return null;
            //var count = data.Tables[0] ;
            return data.Tables[0];
        }

        public DataTable GetProductGroupReport(string where = "", string orderBy = "")
        {
            string sql =
                " select * from (select Max(T_BillItem.ProductId) as ProductId,Max(T_BillItem.ItemName) as ItemName,Max(T_Tree.Name) as TreeName,Sum(T_BillItem.Amount) as Amount  " +
                " from " +
                "  ((T_BillItem inner join T_Product on T_BillItem.ProductId=T_Product.Id) " +
                "  inner join T_Bill on T_BillItem.BillId=T_Bill.Id)   " +
                "  inner join T_Tree on T_Product.TreeId=T_Tree.Id   ";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            sql += " group by  T_BillItem.ProductId) as r ";

            sql = sql + " order by r.ItemName asc";
            if (string.IsNullOrEmpty(orderBy)) sql = sql + orderBy;
            var data = Spa.RunSqLcmdDataSet(sql);
            if (data.Tables.Count == 0) return null;
            //var count = data.Tables[0] ;
            return data.Tables[0];
        }

        public DataTable GetBillView(string where = "", string orderBy = "")
        {
            string sql = " select T_Bill.*,T_Member.Name as MemberName,T_Member.CardId,T_Shop.Name as ShopName,T_Tree.Name as TreeName " +
                         " from ((T_Bill inner join T_Member on T_Bill.MemberId=T_Member.Id) " +
                         " inner join T_Shop on T_Bill.ShopId=T_Shop.Id) " +
                         " inner join T_Tree on T_Bill.TreeId=T_Tree.Id";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            //sql = sql + " order by T_Bill.AddTime desc ";
            if (!string.IsNullOrEmpty(orderBy)) sql = sql + orderBy;
            var data = Spa.RunSqLcmdDataSet(sql);
            if (data == null) return new DataTable();
            if (data.Tables.Count == 0) return new DataTable();
            return data.Tables[0];
        }

        public V_Bill GetBillViewObject(string where = "", string orderBy = "")
        {
            string sql = " select T_Bill.*,T_Member.Name as MemberName,T_Member.HaveValue,T_Member.TelNum,T_Member.CardId,T_Shop.Name as ShopName from (T_Bill inner join T_Member on T_Bill.MemberId=T_Member.Id) inner join T_Shop on T_Bill.ShopId=T_Shop.Id ";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            sql = sql + " order by T_Bill.AddTime desc";
            if (!string.IsNullOrEmpty(orderBy)) sql = sql + where;
            var data = Spa.SelectWhere<V_Bill>(sql).ToList();
            if (!data.Any()) return null;
            return data[0];
        }

        public T_Bill GetBill(string where = "", string orderBy = "")
        {
            var data = Spa.Where<T_Bill>(where).ToList();
            if (!data.Any()) return null;
            return data[0];
        }

        public DataTable GetBillItemView(string where = "")
        {
            string sql = " select T_BillItem.*,T_Bill.AddTime from T_BillItem inner join T_Bill on T_Bill.Id = T_BillItem.BillId";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            var data = Spa.RunSqLcmdDataSet(sql);
            if (data.Tables.Count == 0) return new DataTable();
            return data.Tables[0];
        }

        public DataTable GetBillDinnerSaleView(string where = "")
        {
            string sql = " select Max(T_Bill.AddTime) as AddTime,Max(T_Dinner.Name) as DinnerName " +
                         " from (T_Bill inner join T_BillItem on T_Bill.Id = T_BillItem.BillId) " +
                         " inner join T_Dinner on T_Dinner.Id=T_BillItem.DinnerId ";
            if (!string.IsNullOrEmpty(where)) sql = sql + where;
            sql = sql + " group by T_Bill.Id";
            var data = Spa.RunSqLcmdDataSet(sql);
            if (data.Tables.Count == 0) return new DataTable();
            return data.Tables[0];
        }

        public List<T_BillItem> GetBillItems(string where = "")
        {
            var data = Spa.Where<T_BillItem>(where).ToList();
            if (!data.Any()) return null;
            return data;
        }
        public int Save(T_Bill bill, List<T_BillItem> billItems)
        {
            bool add = true;
            if (string.IsNullOrEmpty(bill.Id))
            {
                bill.Id = Guid.NewGuid().ToString("D");
                bill.State = "已保存";
                bill.AddTime = DateTime.Now;
                Spa.SetCountNo("T_Bill", bill.BillNo);
            }
            else
            {
                add = false;
                var rBillItems = Spa.Where<T_BillItem>(" BillId = '" + bill.Id + "'").ToList();
                if (rBillItems.Any()) Spa.DeleteObjects(rBillItems);
            }
            foreach (var billitem in billItems)
            {
                billitem.BillId = bill.Id;
            }
            bill.NeedPay = Convert.ToInt32(billItems.Where(m => m.IsGift != "是").Sum(m => m.Amount * m.Price * m.Discount));
            bill.OwedMoney = bill.NeedPay;
            if (add) Spa.AddObject(bill);
            else Spa.UpdateObject(bill);
            Spa.AddObjects(billItems);

            var dinnerSaleItems = billItems.Where(m => m.DinnerSaleId != null).ToList();
            if (dinnerSaleItems.Any())
            {
                bill.PayType = "次卡消费";
                bill.RealPay = bill.NeedPay;
                var dinnerSaleIds = dinnerSaleItems.GroupBy(m => m.DinnerSaleId).ToList();
                foreach (var dinnerSaleId in dinnerSaleIds)
                {
                    var dinnerSale = LgcDinnerSale.Where<T_DinnerSale>(m => m.Id == dinnerSaleId.Key).FirstOrDefault();
                    if (dinnerSale == null) continue;
                    dinnerSale.Times = dinnerSale.Times - 1;
                    Spa.UpdateObject(dinnerSale);
                }
            }
            int row = Spa.SaveChanges();
            return row;
        }

        public int Pay(T_Bill bill, string valueRecordSubtractPrice="")
        {
            var billItems = Spa.Where<T_BillItem>(m => m.BillId == bill.Id).ToList();
            decimal sum=billItems.Where(m => m.IsGift != "是").Sum(m => m.Price * m.Amount);
            bill.State = "已结算";
            if (bill.CashPay > 0) bill.PayType = "现金";
            if (bill.BankPay > 0) bill.PayType = "银行卡";
            if (bill.ValuePay > 0) bill.PayType = "充值卡";
            if (bill.MarkPay > 0) bill.PayType = "积分兑换";
            //if (bill. > 0) bill.PayType = "充值卡";
            bill.PayTime = DateTime.Now;
            T_Member member = Spa.Where<T_Member>(m => m.Id == bill.MemberId).FirstOrDefault();
            member.OwedMoney += bill.OwedMoney;
            if (valueRecordSubtractPrice == "是")
            {
                if (sum > member.HaveValue)
                    member.HaveValue = 0;
                else
                    member.HaveValue -= sum;
            }
            else
                member.HaveValue -= bill.ValuePay;
            if (bill.PayType != "次卡消费") bill.RealPay = bill.CashPay + bill.ValuePay + bill.BankPay;
            Spa.UpdateObject(member);
            Spa.UpdateObject(bill);
            int row = Spa.SaveChanges();

            var lMoney = new L_Money
            {
                TreeId = "dc3166e5-75be-4cbf-b02c-30b8e6bc50cb",
                TreeName = "客户消费开单",
                Type = "收入",
                ObjectId = bill.Id,
                CardId = member.CardId,
                BankPayMoney = bill.BankPay,
                CashPayMoney = bill.CashPay,
                BankAccountId = bill.BankAccountId,
                AdminId = bill.AdminId,
                ShopId = bill.ShopId
            };
            if (bill.PayType != "次卡消费") row += MoneyBll.AddMoeny(lMoney);

            List<L_CalculateStore> list = new List<L_CalculateStore>();
            foreach (var item in billItems)
            {
                list.Add(new L_CalculateStore
                {
                    Amount = item.Amount,
                    Pos = item.Pos,
                    IsProject = item.IsProject,
                    ProductId = item.ProductId
                });
            }
            LgcProduct.CalculateStoreAmount(list);
            LgcProduct.CalculateBorakerage(bill,billItems);
            LgcProduct.BillPayStoreIO(bill, billItems);
            return row;
        }

        #endregion

        #region Product
        #endregion

        #endregion
    }
}

